package ru.compscicenter.uno.controller;

import ru.compscicenter.uno.net.TCPClient;
import ru.compscicenter.uno.net.UDPClient;
import ru.compscicenter.uno.log.Logger;
import ru.compscicenter.uno.model.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

/**
 * User: SLeeP
 * Date: 04.11.11
 * Time: 18:14
 */
public class ClientController extends AController {
    private TCPClient tcpClient;
    private boolean toListen = true;

    public ClientController(boolean toListen, boolean isServer) {
        super(isServer);
        this.toListen = toListen;
    }
    
    public void connect(String ip, String name) throws IOException {
        String[] addr = ip.split(":");
        tcpClient = new TCPClient(this, addr[0], Integer.parseInt(addr[1]));
        tcpClient.connect(name);
    }

    public void runTCPClient() {
        tcpClient.toRun = true;
        tcpClient.start();
    }

    public void stopTCPClient() {
        tcpClient.toRun = false;
    }

    public ArrayList<String> getConnectedPlayersNames() {
        if (tcpClient != null) {
            return tcpClient.getConnectedNames();
        } else {
            return null;
        }
    }
    
    public String getRespond() throws IOException{
        return tcpClient.receive();
    }

    public void disconnect() throws IOException {
        tcpClient.disconnect();
    }
    
    public Rules receiveRules() throws IOException {
        return tcpClient.receiveRules();
    }
                                      

    public void doServerSearch() throws IOException {
        String server = "";
        if (toListen) {
            final UDPClient udpClient = new UDPClient();
            udpClient.findServers();
            //server = udpClient.chooseServer();
            String[] addr = server.split(":");
            try {
                tcpClient = new TCPClient(this, addr[0], Integer.parseInt(addr[1]));
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("Write UNO server IP:");
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

            while (tcpClient == null)
            try {
                server = br.readLine();
                String[] addr = server.split(":");
                tcpClient = new TCPClient(this, addr[0], Integer.parseInt(addr[1]));
            } catch (IOException | IllegalArgumentException e) {
                System.out.println("Wrong server IP");
                tcpClient = null;
                //e.printStackTrace();
            }
        }


        tcpClient.setDaemon(true);
        tcpClient.connect("lala");
        tcpClient.start();
    }


    public void run() {
/*        try {
            doServerSearch();
        } catch (IOException e) {
            e.printStackTrace();
        }
        */
    }

    @Override
    public boolean startGame() {
        Logger.write("You are not a server and not allowed to start new game!", Logger.Mode.ACTION);
        return false;
    }

    @Override
    public boolean startRound() {
        String command = ServerController.DO_START_ROUND;
        try {
            tcpClient.send(command);
        } catch (IOException e) {
            Logger.write("Failed to send command" +  command + " " + e.toString(), Logger.Mode.ERROR);
        }
        lastOperationSucceed = -1;
        while (lastOperationSucceed == -1) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Logger.write(e.toString(), Logger.Mode.ERROR);
            }
        }

        if (lastOperationSucceed == 1) {
            lastOperationSucceed = -1;
            return true;
        } else {
            lastOperationSucceed = -1;
            return false;
        }
    }

    @Override
    public boolean doDropCard(int playerId, int cardId) {
        String command = ServerController.DO_DROP_CARD + " " + playerId + " " + cardId;
        try {
            tcpClient.send(command);
        } catch (IOException e) {
            Logger.write("Failed to send command" +  command + " " + e.toString(), Logger.Mode.ERROR);
        }
        lastOperationSucceed = -1;
        while (lastOperationSucceed == -1) {
            //System.out.println("xxxx");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Logger.write(e.toString(), Logger.Mode.ERROR);
            }
        }

        if (lastOperationSucceed == 1) {
            lastOperationSucceed = -1;
            return true;
        } else {
            lastOperationSucceed = -1;
            return false;
        }
    }

    @Override
    public boolean doDropCard(int playerId, int cardId, Card.Color selectedColor) {
        String command = ServerController.DO_DROP_CARD + " " + playerId + " " + cardId + " " + selectedColor;
        try {
            tcpClient.send(command);
        } catch (IOException e) {
            Logger.write("Failed to send command" +  command + " " + e.toString(), Logger.Mode.ERROR);
        }
        lastOperationSucceed = -1;
        while (lastOperationSucceed == -1) {
            //System.out.println("xxxx");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Logger.write(e.toString(), Logger.Mode.ERROR);
            }
        }

        if (lastOperationSucceed == 1) {
            lastOperationSucceed = -1;
            return true;
        } else {
            lastOperationSucceed = -1;
            return false;
        }
    }

    @Override
    public boolean doTakeCard(int playerId) {
        String command = ServerController.DO_TAKE_CARD + " " + playerId; 
        try {
            tcpClient.send(command);
        } catch (IOException e) {
            Logger.write("Failed to send command" +  command + " " + e.toString(), Logger.Mode.ERROR);
        }
        lastOperationSucceed = -1;
        while (lastOperationSucceed == -1) {
            //System.out.println("xxxx");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Logger.write(e.toString(), Logger.Mode.ERROR);
            }
        }

        if (lastOperationSucceed == 1) {
            lastOperationSucceed = -1;
            return true;
        } else {
            lastOperationSucceed = -1;
            return false;
        }
    }

    @Override
    public boolean doSayUno(int playerId) {
        String command = DO_SAY_UNO + " " + playerId;
        try {
            tcpClient.send(command);
        } catch (IOException e) {
            Logger.write("Failed to send command" +  command + " " + e.toString(), Logger.Mode.ERROR);
        }
        lastOperationSucceed = -1;
        while (lastOperationSucceed == -1) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Logger.write(e.toString(), Logger.Mode.ERROR);
            }
        }

        if (lastOperationSucceed == 1) {
            lastOperationSucceed = -1;
            return true;
        } else {
            lastOperationSucceed = -1;
            return false;
        }
    }

    @Override
    public boolean doSomebodyDidntSayUno(int playerId, int whoDidntSayUnoId) {
        String command = DO_SAY_NO_UNO + " " + playerId + " " + whoDidntSayUnoId;
        try {
            tcpClient.send(command);
        } catch (IOException e) {
            Logger.write("Failed to send command" +  command + " " + e.toString(), Logger.Mode.ERROR);
        }
        lastOperationSucceed = -1;
        while (lastOperationSucceed == -1) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Logger.write(e.toString(), Logger.Mode.ERROR);
            }
        }

        if (lastOperationSucceed == 1) {
            lastOperationSucceed = -1;
            return true;
        } else {
            lastOperationSucceed = -1;
            return false;
        }
    }

    @Override
    public boolean doEndTurn(int playerId) {
        String command = DO_END_TURN + " " + playerId;
        try {
            tcpClient.send(command);
        } catch (IOException e) {
            Logger.write("Failed to send command" +  command + " " + e.toString(), Logger.Mode.ERROR);
        }
        lastOperationSucceed = -1;
        while (lastOperationSucceed == -1) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Logger.write(e.toString(), Logger.Mode.ERROR);
            }
        }

        if (lastOperationSucceed == 1) {
            lastOperationSucceed = -1;
            return true;
        } else {
            lastOperationSucceed = -1;
            return false;
        }
    }

    public boolean isServer() {
        return isServer;
    }
}
